/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Persistencia.Oracle;

import Persistencia.IBoletaSenasaDAO;
import Persistencia.Entidades.BoletaSenasa;
import Persistencia.Entidades.PagoSenasa;
import Persistencia.Entidades.Sanitario;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import oracle.jdbc.OraclePreparedStatement;
import oracle.jdbc.OracleTypes;
import utilidades.FormatDateString;

/**
 *
 * @author zeta
 */
public class BoletaSenasaOracleDAO implements IBoletaSenasaDAO {

    private static BoletaSenasaOracleDAO INSTANCE = null;

    /*
     * El contrustcor private no permite que se genere un constructor por defecto
     */
    private BoletaSenasaOracleDAO() {
    }

    private synchronized static void createInstance() {
        if (INSTANCE == null) {
            INSTANCE = new BoletaSenasaOracleDAO();
        }
    }

    public static BoletaSenasaOracleDAO getInstance() {
        if (INSTANCE == null) {
            createInstance();
        }
        return INSTANCE;
    }

    public Integer insertBoletaSenasa(BoletaSenasa boletaSenasa) {
        String sql = "INSERT INTO BOLETASSENASA(NUM_BOLETA,CONCEPTO,VALOR,PAGA,FECHA_ENTREGA)"
                + "VALUES(?,?,?,?,TO_DATE(?, 'DD/MM/RRRR')) RETURNING NUM_BOLETA INTO ? ";
        Connection conn = OracleDAOFactory.getConnection();
        try {


            OraclePreparedStatement pst = (OraclePreparedStatement) conn.prepareStatement(sql);
            pst.setInt(1, boletaSenasa.getNumBoleta());
            pst.setString(2, boletaSenasa.getConcepto());
            pst.setFloat(3, boletaSenasa.getValor());
            pst.setBoolean(4, boletaSenasa.getPaga());
            pst.setString(5, FormatDateString.deDateString(boletaSenasa.getFechaEntrega()));
            pst.registerReturnParameter(6, OracleTypes.NUMBER);
            //inicia Transaccion
            conn.setAutoCommit(false);
            pst.executeUpdate();
            if (boletaSenasa.getSanitariosList() == null) {
                conn.commit();

            } else {
                Iterator<Sanitario> e = boletaSenasa.getSanitariosList().iterator();
                while (e.hasNext()) {
                    Sanitario sanit = e.next();
                    String sql1 = "INSERT INTO SANITARIOBOLETAS(NUM_SANITARIO, NUM_BOLETA) VALUES(?,?)";
                    OraclePreparedStatement pst1 = (OraclePreparedStatement) conn.prepareStatement(sql1);
                    pst1.setInt(1, boletaSenasa.getNumBoleta());
                    pst1.setInt(1, sanit.getNumSanitario());
                    pst1.execute();
                }
                conn.commit();
            }
            ResultSet rs = pst.getReturnResultSet();
            if (rs.next()) {
                return rs.getInt(1);
            }
            return null;
        } catch (SQLException ex) {
            try {
                conn.rollback();
            } catch (SQLException ex1) {
                ex1.printStackTrace();
            }
            ex.printStackTrace();
            return null;
        } finally {
            try {
                conn.setAutoCommit(true);
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }
    }

    public boolean updateBoletaSenasa(BoletaSenasa boletaSenasa) {
        if (!boletaSenasa.getPaga()) {
            String sql = "UPDATE BOLETASSENASA SET CONCEPTO=?,VALOR=?"
                    + "FECHA_ENTREGA=TO_DATE(?, 'DD/MM/RRRR') WHERE NUM_BOLETA = ?";

            Connection conn = OracleDAOFactory.getConnection();
            try {


                OraclePreparedStatement pst = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql);
                pst.setString(1, boletaSenasa.getConcepto());
                pst.setFloat(2, boletaSenasa.getValor());
                pst.setString(3, FormatDateString.deDateString(boletaSenasa.getFechaEntrega()));
                pst.setInt(4, boletaSenasa.getNumBoleta());

                //inicia Transaccion
                conn.setAutoCommit(false);
                pst.executeUpdate();
                String sql1 = "DELETE FROM SANITARIOBOLETAS WHERE NUM_BOLETA=?";
                OraclePreparedStatement pst1 = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql1);
                pst1.setInt(1, boletaSenasa.getNumBoleta());
                pst1.executeUpdate();
                if (boletaSenasa.getSanitariosList().isEmpty()) {

                    conn.commit();
                } else {
                    Iterator<Sanitario> e = boletaSenasa.getSanitariosList().iterator();
                    while (e.hasNext()) {
                        Sanitario sanit = e.next();
                        String sql2 = "INSERT INTO SANITARIOBOLETAS(NUM_SANITARIO, NUM_BOLETA) VALUES(?,?)";
                        OraclePreparedStatement pst2 = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql1);
                        pst2.setInt(1, boletaSenasa.getNumBoleta());
                        pst2.setInt(1, sanit.getNumSanitario());
                        pst2.execute();
                    }
                    conn.commit();
                }

                return true;
            } catch (SQLException ex) {
                ex.printStackTrace();
                try {
                    conn.rollback();
                } catch (SQLException ex1) {
                    ex1.printStackTrace();
                }
                return false;
            } finally {
                try {
                    conn.setAutoCommit(true);
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
        }
        /*
         * else{
         * trhow new BoletaPagaException(La Boleta ya esta Paga);
         * }
         */
        return false;
    }

    public boolean deleteBoletaSenasa(BoletaSenasa boletaSenasa) {
        if (!boletaSenasa.getPaga()) {
            try {
                String sql = "DELETE BOLETASSENASA WHERE NUM_BOLETA = ?";
                OraclePreparedStatement pst = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql);
                pst.setInt(1, boletaSenasa.getNumBoleta());
                pst.executeUpdate();
                return true;
            } catch (SQLException ex) {
                ex.printStackTrace();
                return false;
            }
        }
        /*
         * else{
         * trhow new BoletaPagaException(La Boleta ya esta Paga);
         * }
         */
        return false;
    }

    public BoletaSenasa getBoletaSenasa(Integer numBoleta, boolean conSanitario) {
        String sql = "SELECT NUM_BOLETA, CONCEPTO, VALOR, PAGA, FECHA_ENTREGA"
                + " FROM BOLETASSENASA WHERE NUM_BOLETA = ? ";
        try {

            OraclePreparedStatement pst = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql);
            pst.setInt(1, numBoleta);
            ResultSet rs = pst.executeQuery();
            if (rs.next()) {
                BoletaSenasa boletaSenasa = new BoletaSenasa();
                boletaSenasa.setNumBoleta(rs.getInt("NUM_BOLETA"));
                boletaSenasa.setConcepto(rs.getString("CONCEPTO"));
                boletaSenasa.setValor(rs.getFloat("VALOR"));
                boletaSenasa.setPaga(rs.getString("PAGA").equals("0") ? false : true);
                //comprobar q funcione
                boletaSenasa.setFechaEntrega(new java.util.Date(rs.getDate("FECHA_ENTREGA").getTime()));
                if (conSanitario) {
                    SanitarioOracleDAO.getInstance().getAllSanitarios(boletaSenasa, false);
                }
                return boletaSenasa;
            } else {
                return null;
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
            return null;
        }
    }

   

    public List<BoletaSenasa> getAllBoletasSenasa(boolean conSanitario) {
        String sql = "SELECT NUM_BOLETA, CONCEPTO, VALOR, PAGA, FECHA_ENTREGA FROM BOLETASSENASA";

        try {
            OraclePreparedStatement pst = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql);
            ResultSet rs = pst.executeQuery();
            List<BoletaSenasa> lBoletaSenasa = new ArrayList();
            while (rs.next()) {
                BoletaSenasa boletaSenasa = new BoletaSenasa();
                boletaSenasa.setNumBoleta(rs.getInt("NUM_BOLETA"));
                boletaSenasa.setConcepto(rs.getString("CONCEPTO"));
                boletaSenasa.setValor(rs.getFloat("VALOR"));
                //  boolean b
                //       b = rs.getString("PAGA").equals('0') ? false : true;
                boletaSenasa.setPaga(rs.getString("PAGA").equals("0") ? false : true);
                boletaSenasa.setFechaEntrega(new java.util.Date(rs.getDate("FECHA_ENTREGA").getTime()));
                if (conSanitario) {
                   SanitarioOracleDAO.getInstance().getAllSanitarios(boletaSenasa, false);
                }
                lBoletaSenasa.add(boletaSenasa);
            }

            return lBoletaSenasa;
        } catch (SQLException ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public boolean getAllBoletasSenasa(PagoSenasa pagoSenasa, boolean conSanitario) {
        String sql = "SELECT BOLETASSENASA.NUM_BOLETA,CONCEPTO, VALOR, PAGA, FECHA_ENTREGA FROM PAGOBOLETAS "
                + "INNER JOIN BOLETASSENASA ON BOLETASSENASA.NUM_BOLETA = PAGOBOLETAS.NUM_BOLETA WHERE PAGOBOLETAS.NUM_PAGO = ?";

        try {
            OraclePreparedStatement pst = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql);
            pst.setInt(1, pagoSenasa.getNumPago());
            ResultSet rs = pst.executeQuery();
            List<BoletaSenasa> lBoletaSenasa = new ArrayList();
            while (rs.next()) {
                BoletaSenasa boletaSenasa = new BoletaSenasa();
                boletaSenasa.setNumBoleta(rs.getInt("NUM_BOLETA"));
                boletaSenasa.setConcepto(rs.getString("CONCEPTO"));
                boletaSenasa.setValor(rs.getFloat("VALOR"));
                //  boolean b
                //       b = rs.getString("PAGA").equals('0') ? false : true;
                boletaSenasa.setPaga(rs.getString("PAGA").equals("0") ? false : true);
                boletaSenasa.setFechaEntrega(new java.util.Date(rs.getDate("FECHA_ENTREGA").getTime()));
                if (conSanitario) {
                    SanitarioOracleDAO.getInstance().getAllSanitarios(boletaSenasa, false);
                }
                lBoletaSenasa.add(boletaSenasa);
            }
            pagoSenasa.setBoletasSenasaList(lBoletaSenasa);
            return true;
        } catch (SQLException ex) {
            ex.printStackTrace();
            return false;
        }
    }

    public List<BoletaSenasa> getAllBoletasSenasaSinSanitario() {
        String sql = " SELECT NUM_BOLETA, CONCEPTO, VALOR, PAGA, FECHA_ENTREGA"
                + " FROM BOLETASSENASA WHERE NOT EXISTS(SELECT NUM_SANITARIO"
                + " FROM SANITARIOBOLETAS WHERE "
                + "BOLETASSENASA.NUM_BOLETA = SANITARIOBOLETAS.NUM_BOLETA)";

        try {
            OraclePreparedStatement pst = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql);
            ResultSet rs = pst.executeQuery();
            List<BoletaSenasa> lBoletaSenasa = new ArrayList();
            while (rs.next()) {
                BoletaSenasa boletaSenasa = new BoletaSenasa();
                boletaSenasa.setNumBoleta(rs.getInt("NUM_BOLETA"));
                boletaSenasa.setConcepto(rs.getString("CONCEPTO"));
                boletaSenasa.setValor(rs.getFloat("VALOR"));
                //  boolean b
                //       b = rs.getString("PAGA").equals('0') ? false : true;
                boletaSenasa.setPaga(rs.getString("PAGA").equals("0") ? false : true);
                boletaSenasa.setFechaEntrega(new java.util.Date(rs.getDate("FECHA_ENTREGA").getTime()));

                lBoletaSenasa.add(boletaSenasa);
            }

            return lBoletaSenasa;
        } catch (SQLException ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public List<BoletaSenasa> getAllBoletasSenasaSinPagar(boolean conSanitario) {
        String sql = " SELECT NUM_BOLETA, CONCEPTO, VALOR, PAGA, FECHA_ENTREGA FROM"
                + " BOLETASSENASA WHERE PAGA = 0 ";

        try {
            OraclePreparedStatement pst = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql);
            ResultSet rs = pst.executeQuery();
            List<BoletaSenasa> lBoletaSenasa = new ArrayList();
            while (rs.next()) {
                BoletaSenasa boletaSenasa = new BoletaSenasa();
                boletaSenasa.setNumBoleta(rs.getInt("NUM_BOLETA"));
                boletaSenasa.setConcepto(rs.getString("CONCEPTO"));
                boletaSenasa.setValor(rs.getFloat("VALOR"));
                //  boolean b
                //       b = rs.getString("PAGA").equals('0') ? false : true;
                boletaSenasa.setPaga(rs.getString("PAGA").equals("0") ? false : true);
                boletaSenasa.setFechaEntrega(new java.util.Date(rs.getDate("FECHA_ENTREGA").getTime()));
                if (conSanitario) {
                   SanitarioOracleDAO.getInstance().getAllSanitarios(boletaSenasa, false);
                }
                lBoletaSenasa.add(boletaSenasa);
            }

            return lBoletaSenasa;
        } catch (SQLException ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public List<BoletaSenasa> getAllBoletasSenasaSinPago(boolean conSanitario) {
        String sql = " SELECT NUM_BOLETA, CONCEPTO, VALOR, PAGA, FECHA_ENTREGA FROM"
                + " BOLETASSENASA WHERE NOT EXISTS(SELECT NUM_BOLETA FROM PAGOBOLETAS "
                + "WHERE BOLETASSENASA.NUM_BOLETA = PAGOBOLETAS.NUM_BOLETA)";

        try {
            OraclePreparedStatement pst = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql);
            ResultSet rs = pst.executeQuery();
            List<BoletaSenasa> lBoletaSenasa = new ArrayList();
            while (rs.next()) {
                BoletaSenasa boletaSenasa = new BoletaSenasa();
                boletaSenasa.setNumBoleta(rs.getInt("NUM_BOLETA"));
                boletaSenasa.setConcepto(rs.getString("CONCEPTO"));
                boletaSenasa.setValor(rs.getFloat("VALOR"));
                //  boolean b
                //       b = rs.getString("PAGA").equals('0') ? false : true;
                boletaSenasa.setPaga(rs.getString("PAGA").equals("0") ? false : true);
                boletaSenasa.setFechaEntrega(new java.util.Date(rs.getDate("FECHA_ENTREGA").getTime()));
                if (conSanitario) {
                    SanitarioOracleDAO.getInstance().getAllSanitarios(boletaSenasa, false);
                }
                lBoletaSenasa.add(boletaSenasa);
            }

            return lBoletaSenasa;
        } catch (SQLException ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public boolean getAllBoletasSenasa(Sanitario sanitario, boolean conSanitario) {
        String sql = "SELECT NUM_SANITARIO, NUM_BOLETA FROM SANITARIOBOLETAS WHERE NUM_SANITARIO = ? ";


        try {
            OraclePreparedStatement pst = (OraclePreparedStatement) OracleDAOFactory.getConnection().prepareStatement(sql);
            pst.setInt(1, sanitario.getNumSanitario());
            ResultSet rs = pst.executeQuery();
            List<BoletaSenasa> lBoletaSenasa = new ArrayList();
            while (rs.next()) {
                BoletaSenasa boletaSenasa = getBoletaSenasa(rs.getInt("NUM_BOLETA"), conSanitario);
                if (conSanitario) {
                    SanitarioOracleDAO.getInstance().getAllSanitarios(boletaSenasa, false);
                }
                lBoletaSenasa.add(boletaSenasa);
            }
            sanitario.setBoletasSenasaList(lBoletaSenasa);
            return true;
        } catch (SQLException ex) {
            ex.printStackTrace();
            return false;
        }
    }
}
